Fourier Smoothed Relative Strength Index (FRSI) [Algo Alert]
//@version=5
indicator(title="Fourier Smoothed Relative Strength Index [Algo Alert]", shorttitle="ƒ-RSI [Algo Alert]", format=format.price, precision=2, timeframe="", timeframe_gaps=true)

HA = input.bool(title = 'Heiken Ashi Mode', defval = true)
li = input.bool(title = 'Show leading Oscillator', defval = true, group = "Leading Oscillator")

//======================================================================================================================
//                                                FAST FOURIER TRANSFORM
//======================================================================================================================

//Fast Fourier Transform
import jdehorty/KernelFunctions/2 as kernel

DFT(x, y, Nx, _dir) =>  
    float _arg = 0.0
    float _cos = 0.0
    float _sin = 0.0
    float xArr_i = 0.0
    float yArr_i = 0.0
    xArr = array.new_float(array.size(x))
    yArr = array.new_float(array.size(y))

    for i = 0 to Nx - 1 by 1
        xArr_i := 0.0
        yArr_i := 0.0
        kx = float(i) / float(Nx)
        _arg := -_dir * 2 * math.pi * kx
        for k = 0 to Nx - 1 by 1
            _cos := math.cos(k * _arg)
            _sin := math.sin(k * _arg)
            xArr_i += array.get(x, k) * _cos - array.get(y, k) * _sin
            yArr_i += array.get(x, k) * _sin + array.get(y, k) * _cos
            yArr_i
        array.set(xArr, i, xArr_i)
        array.set(yArr, i, yArr_i)

    if _dir == 1
        for i = 0 to Nx - 1 by 1
            array.set(x, i, array.get(xArr, i) / float(Nx))
            array.set(y, i, array.get(yArr, i) / float(Nx))
    else
        for i = 0 to Nx - 1 by 1
            array.set(x, i, array.get(xArr, i))
            array.set(y, i, array.get(yArr, i))

//======================================================================================================================
//                                                 FOURIER INPUTS
//======================================================================================================================

N = input.int(6,"Fourier Period", group = "Fourier")
xval = input.source(close,"Source",tooltip = "i.e. the source of the discrete Fourier"+
 " transform", group = "Fourier")
// highlighting = input.bool(true,"Highlighting", group = "Fourier")
//smoothing = input.int(10,"Kernel Smoothing", group = "Fourier")

//======================================================================================================================
//                                                 FOURIER CALCULATIONS
//======================================================================================================================

// Fourier transform
x = array.new_float(N, 0.0)
y = array.new_float(N, 0.0)
for i = 0 to N - 1
    array.set(x, i, xval[i])
    array.set(y, i, 0.0)

DFT(x, y, N, 1)

mag = array.new_float(N, 0.0)
for i = 0 to N - 1
    mag_i = math.sqrt(math.pow(array.get(x, i), 2) + math.pow(array.get(y, i), 2))
    array.set(mag, i, mag_i)

dft = array.get(mag,0)

//////////////////////////////// RSI
rsilen = input.int(14,"RSI Length", group = "Relative Strength Index")

up = ta.rma(math.max(ta.change(dft), 0), rsilen)
down = ta.rma(-math.min(ta.change(dft), 0), rsilen)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))

malen = 4

rsicolorgreen = #00ffbb 
rsicolorred = #ff1100

leadosc = 50 + (rsi - ta.ema(rsi, 18))

lii = plot(li ? leadosc : na, color = color.new(#757575, 90) , title = "Leading Oscillator")

v1 = plot(not HA ? rsi : na, color = rsi > ta.ema(rsi, malen) ? rsicolorgreen : rsicolorred, linewidth = 1)
v2 = plot(ta.ema(rsi, malen), display = display.none, linewidth = 1)

mid = plot(50, color=color.new(color.white, 50), title = 'Zero Line')

plotchar(ta.crossover(rsi,ta.ema(rsi, malen)) and not HA ? rsi[1] : na, "Bull Mark", char = "o", location = location.absolute, color = rsicolorgreen, size = size.tiny, offset = -1)
plotchar(ta.crossover(ta.ema(rsi, malen),rsi) and not HA ? rsi[1] : na, "Bear Mark", char = "o", location = location.absolute, color = rsicolorred, size = size.tiny, offset = -1)

fill(v1, v2, color = not HA ? (rsi > ta.ema(rsi, malen) ? rsicolorgreen : rsicolorred) : na, title = 'RSI fill')
//fill(lii, mid, color = leadosc > 50 ? color.new(rsicolorgreen,40) : color.new(rsicolorred,40) )
fill(lii, mid, leadosc > 50 ? leadosc : 50, leadosc > 50 ? 50 : leadosc, leadosc > 50 ? color.new(rsicolorgreen, 50) : #00000000, leadosc > 50 ? #00000000 : color.new(rsicolorred, 50))

//======================================================================================================================
//                                                  Overbought/Oversold Zones
//======================================================================================================================

l1 = plot(100, display = display.none)
l2 = plot(0, display = display.none)
l3 = plot(80, display = display.none)
l4 = plot(20, display = display.none)

fill(l1, l3, top_value = 100, bottom_value = 80, top_color = color.new(rsicolorred, 50), bottom_color = color.new(rsicolorred, 90))
fill(l2, l4, top_value = 20, bottom_value = 0, top_color = color.new(rsicolorgreen, 90), bottom_color = color.new(rsicolorgreen, 50))

plotchar((ta.crossover(rsi, 10) and leadosc > 50) or (ta.crossover(rsi, 20) and (leadosc > 50)) ? -5 : na, char = "▲", color = rsicolorgreen, location = location.absolute, size = size.tiny)
plotchar((ta.crossunder(rsi, 90) and leadosc < 50) or (ta.crossunder(rsi, 80) and (leadosc < 50)) ? 105 : na, char = "▼", color = rsicolorred, location = location.absolute, size = size.tiny)

plotchar((ta.crossover(rsi, 10) and not (leadosc > 50)) or (ta.crossover(rsi, 20) and not (leadosc > 50)) ? -5 : na, char = "∧", color = rsicolorgreen, location = location.absolute, size = size.tiny)
plotchar((ta.crossunder(rsi, 90) and not (leadosc < 50)) or (ta.crossunder(rsi, 80) and not (leadosc < 50)) ? 105 : na, char = "∨", color = rsicolorred, location = location.absolute, size = size.tiny)

plotchar(rsi > 80 and ta.crossunder(rsi,ta.ema(rsi, malen)) and not ta.crossunder(rsi, 90) ? 100 : na, char = "⁕", color = color.white, location = location.absolute, size = size.tiny)
plotchar(rsi < 20 and ta.crossover(rsi,ta.ema(rsi, malen)) and not ta.crossover(rsi, 10) ? 0 : na, char = "⁕", color = color.white, location = location.absolute, size = size.tiny)

o_rsi = rsi[1]
h_rsi = math.max(rsi, rsi[1])
l_rsi = math.min(rsi, rsi[1])
c_rsi = rsi

haClose = (o_rsi + h_rsi + l_rsi + c_rsi) / 4
haOpen = float(na)
haOpen := na(haOpen[1]) ? (o_rsi + c_rsi) / 2 : (nz(haOpen[1]) + nz(haClose[1])) / 2
haHigh = math.max(h_rsi, math.max(haOpen, haClose))
haLow = math.min(l_rsi, math.min(haOpen, haClose))

plotcandle(haOpen, haHigh, haLow, haClose, "Heiken Ashi RSI", haClose > haOpen ? rsicolorgreen : rsicolorred, haClose > haOpen ? rsicolorgreen : rsicolorred, bordercolor = haClose > haOpen ? rsicolorgreen : rsicolorred, display = HA ? display.all : display.none)

alertcondition(ta.crossover(rsi,ta.ema(rsi, malen)), title="Uptrend", message="Go Long! {{exchange}}:{{ticker}}")
alertcondition(ta.crossover(ta.ema(rsi, malen),rsi), title="Downtrend", message="Go Short! {{exchange}}:{{ticker}}")

alertcondition(haClose > haOpen, title="Heiken Ashi Uptrend", message="Go Long! {{exchange}}:{{ticker}}")
alertcondition(haClose < haOpen, title="Heiken Ashi Downtrend", message="Go Short! {{exchange}}:{{ticker}}")

alertcondition((ta.crossover(rsi, 10) and leadosc > 50) or (ta.crossover(rsi, 20) and (leadosc > 50)), title="Strong Bullish Reversal!", message="Strong Bullish Reversal! {{exchange}}:{{ticker}}")
alertcondition((ta.crossunder(rsi, 90) and leadosc < 50) or (ta.crossunder(rsi, 80) and (leadosc < 50)), title="Strong Bearish Reversal!", message="Strong Bearish Reversal! {{exchange}}:{{ticker}}")

alertcondition((ta.crossover(rsi, 10) and not (leadosc > 50)) or (ta.crossover(rsi, 20) and not (leadosc > 50)), title="Weak Bullish Reversal!", message="Weak Bullish Reversal! {{exchange}}:{{ticker}}")
alertcondition((ta.crossunder(rsi, 90) and not (leadosc < 50)) or (ta.crossunder(rsi, 80) and not (leadosc < 50)), title="Weak Bearish Reversal!", message="Weak Bearish Reversal! {{exchange}}:{{ticker}}")

alertcondition(rsi < 20 and ta.crossover(rsi,ta.ema(rsi, malen)) and not ta.crossover(rsi, 10), title="Bullish Take Profit!", message="Bullish Take Profit! {{exchange}}:{{ticker}}")
alertcondition(rsi > 80 and ta.crossunder(rsi,ta.ema(rsi, malen)) and not ta.crossunder(rsi, 90), title="Bearish Take Profit!", message="Bearish Take Profit! {{exchange}}:{{ticker}}")